package com.stable.actor.config;


import java.util.Properties;
import java.util.concurrent.TimeUnit;
import com.typesafe.config.Config;
public class ActorSystemConfig {
    // 系统配置
    private String systemName = "default-system";
    private String hostname = "localhost";
    private int systemPort = 2552;

    // 网络配置
    private long connectionTimeout = 20000;
    private long heartbeatInterval = 2000;
    private long retryInterval = 5000;
    private int maxRetries = 3;

    // 调度器配置
    private int schedulerThreads = 4;
    private String schedulerThreadPrefix = "actor-scheduler";

    // Actor配置
    private int dispatcherThreads = 8;
    private int queueSize = 500;

    // 远程配置
    private boolean remoteEnabled = true;
    private int defaultRemotePort = 2552;
    private long discoveryTimeout = 30000;

    // 默认构造函数
    public ActorSystemConfig() {}

    // 从Properties加载配置
    public static ActorSystemConfig fromProperties(Properties props) {
        ActorSystemConfig config = new ActorSystemConfig();

        // 系统配置
        config.setSystemName(props.getProperty("actor.system.name", "default-system"));
        config.setHostname(props.getProperty("actor.system.hostname", "localhost"));
        config.setSystemPort(Integer.parseInt(props.getProperty("actor.system.port", "2552")));

        // 网络配置
        config.setConnectionTimeout(
                parseDuration(props.getProperty("actor.network.connection-timeout", "20s")));
        config.setHeartbeatInterval(
                parseDuration(props.getProperty("actor.network.heartbeat-interval", "2s")));
        config.setRetryInterval(
                parseDuration(props.getProperty("actor.network.retry-interval", "5s")));
        config.setMaxRetries(Integer.parseInt(props.getProperty("actor.network.max-retries", "3")));

        // 调度器配置
        config.setSchedulerThreads(
                Integer.parseInt(props.getProperty("actor.scheduler.threads", "4")));
        config.setSchedulerThreadPrefix(
                props.getProperty("actor.scheduler.thread-prefix", "actor-scheduler"));

        // Actor配置
        config.setDispatcherThreads(
                Integer.parseInt(props.getProperty("actor.dispatcher.threads", "8")));
        config.setQueueSize(
                Integer.parseInt(props.getProperty("actor.dispatcher.queue-size", "500")));

        // 远程配置
        config.setRemoteEnabled(
                Boolean.parseBoolean(props.getProperty("actor.remote.enabled", "true")));
        config.setDefaultRemotePort(
                Integer.parseInt(props.getProperty("actor.remote.default-port", "2552")));
        config.setDiscoveryTimeout(
                parseDuration(props.getProperty("actor.remote.discovery-timeout", "30s")));

        return config;
    }
    public static ActorSystemConfig fromConfig(Config config) {
        ActorSystemConfig actorConfig = new ActorSystemConfig();

        // 系统配置
        actorConfig.setSystemName(config.getString("actor.system.name"));
        actorConfig.setHostname(config.getString("actor.system.hostname"));
        actorConfig.setSystemPort(config.getInt("actor.system.port"));

        // 网络配置
        actorConfig.setConnectionTimeout(parseDuration(config.getString("actor.network.connection-timeout")));
        actorConfig.setHeartbeatInterval(parseDuration(config.getString("actor.network.heartbeat-interval")));
        actorConfig.setRetryInterval(parseDuration(config.getString("actor.network.retry-interval")));
        actorConfig.setMaxRetries(config.getInt("actor.network.max-retries"));

        // 调度器配置
        actorConfig.setSchedulerThreads(config.getInt("actor.scheduler.threads"));
        actorConfig.setSchedulerThreadPrefix(config.getString("actor.scheduler.thread-prefix"));

        // 分发器配置
        actorConfig.setDispatcherThreads(config.getInt("actor.dispatcher.threads"));
        actorConfig.setQueueSize(config.getInt("actor.dispatcher.queue-size"));

        // 远程通信配置
        actorConfig.setRemoteEnabled(config.getBoolean("actor.remote.enabled"));
        actorConfig.setDefaultRemotePort(config.getInt("actor.remote.default-port"));
        actorConfig.setDiscoveryTimeout(parseDuration(config.getString("actor.remote.discovery-timeout")));

        return actorConfig;
    }

    // 解析时间字符串 (如 "30s", "2m", "1h")
    private static long parseDuration(String durationStr) {
        if (durationStr == null || durationStr.isEmpty()) {
            return 0;
        }

        try {
            if (durationStr.endsWith("ms")) {
                return Long.parseLong(durationStr.substring(0, durationStr.length() - 2));
            } else if (durationStr.endsWith("s")) {
                return TimeUnit.SECONDS.toMillis(
                        Long.parseLong(durationStr.substring(0, durationStr.length() - 1)));
            } else if (durationStr.endsWith("m")) {
                return TimeUnit.MINUTES.toMillis(
                        Long.parseLong(durationStr.substring(0, durationStr.length() - 1)));
            } else if (durationStr.endsWith("h")) {
                return TimeUnit.HOURS.toMillis(
                        Long.parseLong(durationStr.substring(0, durationStr.length() - 1)));
            } else {
                return Long.parseLong(durationStr);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("Invalid duration format: " + durationStr, e);
        }
    }

    // Getter和Setter方法
    public String getSystemName() { return systemName; }
    public ActorSystemConfig setSystemName(String systemName) {
        this.systemName = systemName;
        return this;
    }

    public String getHostname() { return hostname; }
    public ActorSystemConfig setHostname(String hostname) {
        this.hostname = hostname;
        return this;
    }

    public int getSystemPort() { return systemPort; }
    public ActorSystemConfig setSystemPort(int systemPort) {
        this.systemPort = systemPort;
        return this;
    }

    public long getConnectionTimeout() { return connectionTimeout; }
    public ActorSystemConfig setConnectionTimeout(long connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
        return this;
    }

    public long getHeartbeatInterval() { return heartbeatInterval; }
    public ActorSystemConfig setHeartbeatInterval(long heartbeatInterval) {
        this.heartbeatInterval = heartbeatInterval;
        return this;
    }

    public long getRetryInterval() { return retryInterval; }
    public ActorSystemConfig setRetryInterval(long retryInterval) {
        this.retryInterval = retryInterval;
        return this;
    }

    public int getMaxRetries() { return maxRetries; }
    public ActorSystemConfig setMaxRetries(int maxRetries) {
        this.maxRetries = maxRetries;
        return this;
    }

    public int getSchedulerThreads() { return schedulerThreads; }
    public ActorSystemConfig setSchedulerThreads(int schedulerThreads) {
        this.schedulerThreads = schedulerThreads;
        return this;
    }

    public String getSchedulerThreadPrefix() { return schedulerThreadPrefix; }
    public ActorSystemConfig setSchedulerThreadPrefix(String schedulerThreadPrefix) {
        this.schedulerThreadPrefix = schedulerThreadPrefix;
        return this;
    }

    public int getDispatcherThreads() { return dispatcherThreads; }
    public ActorSystemConfig setDispatcherThreads(int dispatcherThreads) {
        this.dispatcherThreads = dispatcherThreads;
        return this;
    }

    public int getQueueSize() { return queueSize; }
    public ActorSystemConfig setQueueSize(int queueSize) {
        this.queueSize = queueSize;
        return this;
    }

    public boolean isRemoteEnabled() { return remoteEnabled; }
    public ActorSystemConfig setRemoteEnabled(boolean remoteEnabled) {
        this.remoteEnabled = remoteEnabled;
        return this;
    }

    public int getDefaultRemotePort() { return defaultRemotePort; }
    public ActorSystemConfig setDefaultRemotePort(int defaultRemotePort) {
        this.defaultRemotePort = defaultRemotePort;
        return this;
    }

    public long getDiscoveryTimeout() { return discoveryTimeout; }
    public ActorSystemConfig setDiscoveryTimeout(long discoveryTimeout) {
        this.discoveryTimeout = discoveryTimeout;
        return this;
    }
}
